home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / mips / include / asm / system.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  5.7 KB  |  223 lines

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
  7.  * Copyright (C) 1996 by Paul M. Antoine
  8.  * Copyright (C) 1999 Silicon Graphics
  9.  * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
  10.  * Copyright (C) 2000 MIPS Technologies, Inc.
  11.  */
  12. #ifndef _ASM_SYSTEM_H
  13. #define _ASM_SYSTEM_H
  14.  
  15. #include <linux/types.h>
  16. #include <linux/irqflags.h>
  17.  
  18. #include <asm/addrspace.h>
  19. #include <asm/barrier.h>
  20. #include <asm/cmpxchg.h>
  21. #include <asm/cpu-features.h>
  22. #include <asm/dsp.h>
  23. #include <asm/watch.h>
  24. #include <asm/war.h>
  25.  
  26.  
  27. /*
  28.  * switch_to(n) should switch tasks to task nr n, first
  29.  * checking that n isn't the current task, in which case it does nothing.
  30.  */
  31. extern asmlinkage void *resume(void *last, void *next, void *next_ti);
  32.  
  33. struct task_struct;
  34.  
  35. #ifdef CONFIG_MIPS_MT_FPAFF
  36.  
  37. /*
  38.  * Handle the scheduler resume end of FPU affinity management.  We do this
  39.  * inline to try to keep the overhead down. If we have been forced to run on
  40.  * a "CPU" with an FPU because of a previous high level of FP computation,
  41.  * but did not actually use the FPU during the most recent time-slice (CU1
  42.  * isn't set), we undo the restriction on cpus_allowed.
  43.  *
  44.  * We're not calling set_cpus_allowed() here, because we have no need to
  45.  * force prompt migration - we're already switching the current CPU to a
  46.  * different thread.
  47.  */
  48.  
  49. #define __mips_mt_fpaff_switch_to(prev)                    \
  50. do {                                    \
  51.     struct thread_info *__prev_ti = task_thread_info(prev);        \
  52.                                     \
  53.     if (cpu_has_fpu &&                        \
  54.         test_ti_thread_flag(__prev_ti, TIF_FPUBOUND) &&        \
  55.         (!(KSTK_STATUS(prev) & ST0_CU1))) {                \
  56.         clear_ti_thread_flag(__prev_ti, TIF_FPUBOUND);        \
  57.         prev->cpus_allowed = prev->thread.user_cpus_allowed;    \
  58.     }                                \
  59.     next->thread.emulated_fp = 0;                    \
  60. } while(0)
  61.  
  62. #else
  63. #define __mips_mt_fpaff_switch_to(prev) do { (void) (prev); } while (0)
  64. #endif
  65.  
  66. #define switch_to(prev, next, last)                    \
  67. do {                                    \
  68.     __mips_mt_fpaff_switch_to(prev);                \
  69.     if (cpu_has_dsp)                        \
  70.         __save_dsp(prev);                    \
  71.     (last) = resume(prev, next, task_thread_info(next));        \
  72. } while (0)
  73.  
  74. #define finish_arch_switch(prev)                    \
  75. do {                                    \
  76.     if (cpu_has_dsp)                        \
  77.         __restore_dsp(current);                    \
  78.     if (cpu_has_userlocal)                        \
  79.         write_c0_userlocal(current_thread_info()->tp_value);    \
  80.     __restore_watch();                        \
  81. } while (0)
  82.  
  83. static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
  84. {
  85.     __u32 retval;
  86.  
  87.     if (cpu_has_llsc && R10000_LLSC_WAR) {
  88.         unsigned long dummy;
  89.  
  90.         __asm__ __volatile__(
  91.         "    .set    mips3                    \n"
  92.         "1:    ll    %0, %3            # xchg_u32    \n"
  93.         "    .set    mips0                    \n"
  94.         "    move    %2, %z4                    \n"
  95.         "    .set    mips3                    \n"
  96.         "    sc    %2, %1                    \n"
  97.         "    beqzl    %2, 1b                    \n"
  98.         "    .set    mips0                    \n"
  99.         : "=&r" (retval), "=m" (*m), "=&r" (dummy)
  100.         : "R" (*m), "Jr" (val)
  101.         : "memory");
  102.     } else if (cpu_has_llsc) {
  103.         unsigned long dummy;
  104.  
  105.         __asm__ __volatile__(
  106.         "    .set    mips3                    \n"
  107.         "1:    ll    %0, %3            # xchg_u32    \n"
  108.         "    .set    mips0                    \n"
  109.         "    move    %2, %z4                    \n"
  110.         "    .set    mips3                    \n"
  111.         "    sc    %2, %1                    \n"
  112.         "    beqz    %2, 2f                    \n"
  113.         "    .subsection 2                    \n"
  114.         "2:    b    1b                    \n"
  115.         "    .previous                    \n"
  116.         "    .set    mips0                    \n"
  117.         : "=&r" (retval), "=m" (*m), "=&r" (dummy)
  118.         : "R" (*m), "Jr" (val)
  119.         : "memory");
  120.     } else {
  121.         unsigned long flags;
  122.  
  123.         raw_local_irq_save(flags);
  124.         retval = *m;
  125.         *m = val;
  126.         raw_local_irq_restore(flags);    /* implies memory barrier  */
  127.     }
  128.  
  129.     smp_llsc_mb();
  130.  
  131.     return retval;
  132. }
  133.  
  134. #ifdef CONFIG_64BIT
  135. static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
  136. {
  137.     __u64 retval;
  138.  
  139.     if (cpu_has_llsc && R10000_LLSC_WAR) {
  140.         unsigned long dummy;
  141.  
  142.         __asm__ __volatile__(
  143.         "    .set    mips3                    \n"
  144.         "1:    lld    %0, %3            # xchg_u64    \n"
  145.         "    move    %2, %z4                    \n"
  146.         "    scd    %2, %1                    \n"
  147.         "    beqzl    %2, 1b                    \n"
  148.         "    .set    mips0                    \n"
  149.         : "=&r" (retval), "=m" (*m), "=&r" (dummy)
  150.         : "R" (*m), "Jr" (val)
  151.         : "memory");
  152.     } else if (cpu_has_llsc) {
  153.         unsigned long dummy;
  154.  
  155.         __asm__ __volatile__(
  156.         "    .set    mips3                    \n"
  157.         "1:    lld    %0, %3            # xchg_u64    \n"
  158.         "    move    %2, %z4                    \n"
  159.         "    scd    %2, %1                    \n"
  160.         "    beqz    %2, 2f                    \n"
  161.         "    .subsection 2                    \n"
  162.         "2:    b    1b                    \n"
  163.         "    .previous                    \n"
  164.         "    .set    mips0                    \n"
  165.         : "=&r" (retval), "=m" (*m), "=&r" (dummy)
  166.         : "R" (*m), "Jr" (val)
  167.         : "memory");
  168.     } else {
  169.         unsigned long flags;
  170.  
  171.         raw_local_irq_save(flags);
  172.         retval = *m;
  173.         *m = val;
  174.         raw_local_irq_restore(flags);    /* implies memory barrier  */
  175.     }
  176.  
  177.     smp_llsc_mb();
  178.  
  179.     return retval;
  180. }
  181. #else
  182. extern __u64 __xchg_u64_unsupported_on_32bit_kernels(volatile __u64 * m, __u64 val);
  183. #define __xchg_u64 __xchg_u64_unsupported_on_32bit_kernels
  184. #endif
  185.  
  186. /* This function doesn't exist, so you'll get a linker error
  187.    if something tries to do an invalid xchg().  */
  188. extern void __xchg_called_with_bad_pointer(void);
  189.  
  190. static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
  191. {
  192.     switch (size) {
  193.     case 4:
  194.         return __xchg_u32(ptr, x);
  195.     case 8:
  196.         return __xchg_u64(ptr, x);
  197.     }
  198.     __xchg_called_with_bad_pointer();
  199.     return x;
  200. }
  201.  
  202. #define xchg(ptr, x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x), (ptr), sizeof(*(ptr))))
  203.  
  204. extern void set_handler(unsigned long offset, void *addr, unsigned long len);
  205. extern void set_uncached_handler(unsigned long offset, void *addr, unsigned long len);
  206.  
  207. typedef void (*vi_handler_t)(void);
  208. extern void *set_vi_handler(int n, vi_handler_t addr);
  209.  
  210. extern void *set_except_vector(int n, void *addr);
  211. extern unsigned long ebase;
  212. extern void per_cpu_trap_init(void);
  213.  
  214. /*
  215.  * See include/asm-ia64/system.h; prevents deadlock on SMP
  216.  * systems.
  217.  */
  218. #define __ARCH_WANT_UNLOCKED_CTXSW
  219.  
  220. extern unsigned long arch_align_stack(unsigned long sp);
  221.  
  222. #endif /* _ASM_SYSTEM_H */
  223.